home *** CD-ROM | disk | FTP | other *** search
- /*
- CDAudioList Version 1.00, 01/09/2000
-
- Shell command to list tracks and CDID found on an audio CD.
-
- Based on Piotr Gapinski (narg@polbox.com) work (acdb,
- written in E) and on the RKRM SCSI_Direct.c example program.
-
- Adapted to C by Roland Florac (roland.florac@fnac.net)
-
- To compile with SAS/C (5056 bytes):
- sc LINK OPT PARM=REGS CDAudioList.c
-
- Installation:
- Just copy the CDAudioList program in your c: directory.
-
- Usage:
- CDAudioList unit [xxx.device]
- scsi.device is used by default
-
- Examples:
- CDAudioList 3 atapi.device
- CDAudioList 3 scsi.device
- CDAudioList 1
- */
-
- #include <stdio.h>
- #include <strings.h>
- #include <stdlib.h>
-
- #include <exec/lists.h>
- #include <exec/memory.h>
- #include <exec/ports.h>
- #include <exec/devices.h>
- #include <exec/io.h>
- #include <devices/scsidisk.h>
- #include <exec/nodes.h>
- #include <dos/dos.h>
-
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <clib/alib_protos.h>
-
- char version[] = "$VER: CDAudioList 1.00 (01/09/2000)";
-
- struct scsicmd10 {
- char opcode;
- char b1, b2, b3, b4, b5, b6, b7, b8;
- char control;
- };
-
- struct msf {
- long min, sec, frm;
- };
-
- struct cdinfo {
- struct msf cdtoc[100];
- char idname[30];
- long tracks, time, cddb;
- };
-
- #define SCSI_CMD_READTOC 0x43
- #define SENSE_LEN 252
- #define MAX_TOC_LEN 804
-
- char scsidata[MAX_TOC_LEN + SENSE_LEN], * tocbuffer;
- struct MsgPort port;
- struct IOStdReq scsio;
-
-
- static void message (char * m)
- {
- Write (Output(), m, strlen(m));
- }
-
- static long CDSetup (char * device, long unit)
- {
- long error;
-
- tocbuffer = scsidata + MAX_TOC_LEN;
-
- port.mp_Node.ln_Pri = 0; /* setup the ReplyPort */
- port.mp_SigBit = AllocSignal (-1);
- port.mp_SigTask = (struct Task *) FindTask (0);
- NewList (&(port.mp_MsgList));
- scsio.io_Message.mn_ReplyPort = &port;
-
- error = OpenDevice (device, unit, &scsio, 0);
- if (error)
- {
- message ("Unable to open specified device\n");
- return FALSE;
- }
- return TRUE;
- }
-
- static void CDCleanUp (void)
- {
- struct Message * msg;
-
- if (scsio.io_Device)
- {
- CloseDevice (&scsio);
- Forbid();
- while (msg = GetMsg (&port))
- ReplyMsg (msg);
- Permit();
- }
- }
-
- static long cddbsum (long n)
- {
- long ret = 0;
-
- while (n > 0)
- {
- ret = (ret + n % 10);
- n = (n / 10);
- }
- return ret;
- }
-
- static long cddb (long trks, struct msf * cdtoc)
- {
- long i = 0, t, n = 0;
-
- while (i < trks)
- {
- n = n + cddbsum(((cdtoc[i].min) * 60) + (cdtoc[i].sec));
- i++;
- }
- n = (n % 255) << 24;
- t = (((cdtoc[trks].min)*60)+(cdtoc[trks].sec)) - (((cdtoc[0].min)*60)+(cdtoc[0].sec));
- t = t << 8;
- return (n | t | trks);
- }
-
- static BYTE doscsicmd (char cmd)
- {
- struct SCSICmd scsicmd;
- struct scsicmd10 command = { SCSI_CMD_READTOC, 0, 0, 0, 0, 0, 0, 3, 0x24, 0 };
-
- command.b1 = cmd;
- scsio.io_Length = sizeof (scsicmd);
- scsio.io_Data = &scsicmd;
- scsio.io_Command = HD_SCSICMD;
-
- scsicmd.scsi_Data = (unsigned short *) tocbuffer;
- scsicmd.scsi_Length = MAX_TOC_LEN;
- scsicmd.scsi_SenseActual = 0;
- scsicmd.scsi_SenseLength = SENSE_LEN;
- scsicmd.scsi_SenseData = scsidata;
- scsicmd.scsi_Command = (unsigned char *) &command;
- scsicmd.scsi_CmdLength = sizeof (struct scsicmd10);
- scsicmd.scsi_Flags = SCSIF_READ | SCSIF_AUTOSENSE;
- scsicmd.scsi_Status = 0;
-
- DoIO (&scsio);
- return scsio.io_Error;
- }
-
- static long fileid (char * cdid)
- {
- long rc, tocsize, tocnumtracks;
- char * tocptr;
- long toctrackaddr[256];
-
- rc = doscsicmd (0);
- if (rc == 0)
- {
- tocsize = (tocbuffer[0] << 8) + tocbuffer[1];
- if (tocsize >= 2) tocsize = tocsize - 2;
- tocptr = tocbuffer + 4;
- tocnumtracks = 0;
-
- while (tocptr < (tocbuffer + 4 + tocsize))
- {
- toctrackaddr[tocnumtracks] = ((tocptr[4] << 24) | (tocptr[5] << 16) | (tocptr[6] << 8) | (tocptr[7]));
- tocnumtracks++;
- tocptr = tocptr + 8;
- }
- tocnumtracks--;
- sprintf (cdid, "CDID %02ld%06lx%06lx\n", tocnumtracks, toctrackaddr[2], toctrackaddr[tocnumtracks], 0);
- }
- return rc;
- }
-
- static long readtocmsf (struct msf * msf)
- {
- long tocsize;
- char * tocptr;
- long tocnumtracks = 0;
-
- if (doscsicmd (2) == 0)
- {
- tocsize = (tocbuffer[0] << 8) + tocbuffer[1];
- if (tocsize >= 2)
- tocsize = tocsize - 2;
- tocptr = tocbuffer + 4;
- tocnumtracks = 0;
-
- while (tocptr < (tocbuffer + 4 + tocsize))
- {
- msf[tocnumtracks].min = tocptr[5];
- msf[tocnumtracks].sec = tocptr[6];
- msf[tocnumtracks].frm = ((tocptr[5]*60)+(tocptr[6]))*75+tocptr[7];
- tocptr = tocptr + 8;
- tocnumtracks++;
- }
- tocnumtracks--;
- }
- return tocnumtracks;
- }
-
- static long CDCreateInfo (struct cdinfo * cd)
- {
- cd->tracks = readtocmsf (&cd->cdtoc[0]);
- if (cd->tracks == 0)
- {
- message ("Cannot read TOC!\n");
- return 0;
- }
- else
- {
- cd->cddb = cddb (cd->tracks, cd->cdtoc);
-
- cd->time = (
- ((cd->cdtoc[cd->tracks].min * 60) + cd->cdtoc[cd->tracks].sec) -
- ((cd->cdtoc[0].min * 60) + cd->cdtoc[0].sec)
- );
- if (fileid (cd->idname))
- {
- message ("Cannot compute CDID file name!\n");
- return 0;
- }
- }
- return 1;
- }
-
- static long CDTrackTime (struct cdinfo * cd, long track, struct msf * msf)
- {
- long time;
-
- if (track >= cd->tracks)
- return FALSE;
- time = ((cd->cdtoc[track + 1].frm) - (cd->cdtoc[track].frm))/75;
- msf->min = time / 60;
- msf->sec = time - msf->min * 60;
- return time;
- }
-
- static long CDTime (struct cdinfo * cd, struct msf * m)
- {
- m->min = cd->time / 60;
- m->sec = cd->time - m->min * 60;
- return cd->time;
- }
-
- void main (int argc, char **argv)
- {
- struct cdinfo cd;
- long i, unit;
- struct msf time;
- char * dname = "scsi.device", m[50];
-
- if ((argc < 2) || (argc > 3))
- {
- sprintf (m, "Usage: %s SCSIunit# [xxxx.device]\n",argv[0]);
- message (m);
- }
- else
- {
- StrToLong (argv[1], &unit);
- if (argc == 3)
- dname = argv[2];
-
- if (CDSetup (dname, unit))
- {
- if (CDCreateInfo (&cd))
- {
- CDTime (&cd, &time);
- sprintf (m, "%ld tracks, total time %ld:%0.2ld\n", cd.tracks, time.min, time.sec);
- message (m);
- for (i = 1; i <= cd.tracks; i++)
- {
- CDTrackTime (&cd, i - 1, &time);
- sprintf (m, "Track %0.2ld: %ld:%0.2ld\n", i, time.min, time.sec);
- message (m);
- }
- message (cd.idname);
- }
- CDCleanUp ();
- }
- }
- }
-